Set environment values (environments)
The environments view modifier allows injecting specific environment values into the current view hierarchy.
It serves a role similar to SwiftUI’s .environment(), but with a more explicit and controlled design tailored for Scripting.
Currently, the modifier supports:
editMode — controls editing behavior in views such as List
openURL — customizes how links are handled when tapped
These environment values affect all descendants within the modified view subtree.
Modifier Definition
1environments?: {
2 editMode?: Observable<EditMode>;
3 openURL?: (url: string) => OpenURLActionResult;
4};
1. editMode Environment
The editMode environment value controls the editing state of views that support editing behavior, such as List with row deletion or movement.
It must be provided as an Observable<EditMode> so views can reactively update when the editing state changes.
EditMode Type
1class EditMode {
2 readonly value: "active" | "inactive" | "transient" | "unknown";
3 readonly isEditing: boolean;
4
5 static active(): EditMode;
6 static inactive(): EditMode;
7 static transient(): EditMode;
8}
Meaning of value
| Value |
Description |
active |
Editing mode is enabled |
inactive |
Editing mode is disabled |
transient |
Temporary transitional state |
unknown |
Undefined or unexpected state |
editMode Example
1const editMode = useObservable(() => EditMode.active())
2
3<List
4 environments={{
5 editMode: editMode
6 }}
7>
8 <ForEach
9 editActions="all"
10 data={items}
11 builder={item => <Text key={item.id}>{item}</Text>}
12 />
13</List>
2. openURL Environment
The openURL environment value customizes how URLs are handled when interacted with inside the view tree.
It overrides the default behavior of components such as <Link>.
This is useful for:
- Deciding whether URLs should open inside the app or externally
- Filtering or validating URLs
- Redirecting URLs to different handlers
Function Signature
1openURL?: (url: string) => OpenURLActionResult;
OpenURLActionResult
1class OpenURLActionResult {
2 type: string;
3
4 static handled(): OpenURLActionResult;
5 static discarded(): OpenURLActionResult;
6
7 static systemAction(options?: {
8 url?: string;
9 /**
10 * Whether the system should prefer opening the URL in-app.
11 * Requires iOS 26.0+.
12 */
13 prefersInApp: boolean;
14 }): OpenURLActionResult;
15}
Result Behavior
| Method |
Meaning |
handled() |
The URL is considered fully handled; default behavior stops |
discarded() |
The URL is ignored |
systemAction() |
Requests the system to open a (possibly modified) URL |
iOS Requirement
prefersInApp requires iOS 26.0+
- On earlier versions, the parameter may have no effect and system defaults will apply
openURL Example
1<Group
2 environments={{
3 openURL: (url) => {
4 return OpenURLActionResult.systemAction({
5 url,
6 prefersInApp: false // Requires iOS 26.0+
7 })
8 }
9 }}
10>
11 {urls.map(url =>
12 <Link url={url}>{url}</Link>
13 )}
14</Group>
Combined Example (editMode + openURL)
1const editMode = useObservable(() => EditMode.inactive())
2
3<VStack
4 environments={{
5 editMode,
6 openURL: (url) => {
7 if (url.startsWith("https://safe.com")) {
8 return OpenURLActionResult.systemAction({
9 url,
10 prefersInApp: true // iOS 26.0+ only
11 })
12 }
13 return OpenURLActionResult.discarded()
14 }
15 }}
16>
17 <Button
18 title="Toggle Edit"
19 action={() => {
20 editMode.value = editMode.value.isEditing
21 ? EditMode.inactive()
22 : EditMode.active()
23 }}
24 />
25
26 <List>
27 ...
28 </List>
29
30 <Link url="https://safe.com">Safe Link</Link>
31 <Link url="https://blocked.com">Blocked Link</Link>
32</VStack>
Notes & Behavior Summary
- The
environments modifier applies only to the subtree where it is used.
editMode must be an Observable<EditMode> for reactive updates.
openURL replaces default URL-handling behavior for all descendant views.
- Returning
handled() stops further URL processing.
systemAction() delegates handling back to the system.
prefersInApp requires iOS 26.0+ and may be ignored on earlier versions.
- Scripting’s environment system is explicit—only the values you define are injected.